package gek.uni.aspirant.uml.utils.providers;

import java.util.Collection;

import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.UMLPackage;

public class UmlContentProvider implements ITreeContentProvider {

  public UmlContentProvider() {
    super();
  }

  @SuppressWarnings("unchecked")
  @Override
  public Object[] getChildren(Object parentElement) {
    if (parentElement instanceof Model)
      return EcoreUtil.getObjectsByType(
          ((Model) parentElement).getPackagedElements(),
          UMLPackage.Literals.PACKAGE).toArray();
    else if (parentElement instanceof Package) {
      Collection result = (EcoreUtil.getObjectsByType(((Package) parentElement)
          .getPackagedElements(), UMLPackage.Literals.PACKAGE));
      result.addAll(EcoreUtil.getObjectsByType(((Package) parentElement)
          .getPackagedElements(), UMLPackage.Literals.CLASS));
      return result.toArray();
    } else if (parentElement instanceof Class)
      return ((org.eclipse.uml2.uml.Class) parentElement).getAllOperations()
          .toArray();
    else
      return null;
  }

  @Override
  public Object getParent(Object element) {
    if (element instanceof Model)
      return null;
    else if (element instanceof Package)
      return ((Package) element).getModel();
    else if (element instanceof Class)
      return ((Class) element).getPackage();
    else if (element instanceof Operation)
      return ((Operation) element).getClass_();
    else
      return null;
  }

  @Override
  public boolean hasChildren(Object element) {
    if (element instanceof Model)
      return ((Model) element).getPackagedElements().size() > 0;
    else if (element instanceof Package)
      return ((Package) element).getPackagedElements().size() > 0;
    else if (element instanceof Class)
      return ((Class) element).getOperations().size() > 0;
    else
      return false;
  }

  @Override
  public Object[] getElements(Object inputElement) {
    if (inputElement instanceof Resource)
      return EcoreUtil.getObjectsByType(
          ((Resource) inputElement).getContents(), UMLPackage.Literals.MODEL)
          .toArray();

    else if (inputElement instanceof Model) {
      return EcoreUtil.getObjectsByType(
          ((Model) inputElement).getPackagedElements(),
          UMLPackage.Literals.PACKAGE).toArray();
    }

    else if (inputElement instanceof Object[])
      return (Object[]) inputElement;
    else
      return new Object[0];
  }

  @Override
  public void dispose() {

  }

  @Override
  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
  }

}
